package middleware

import (
	"bytes"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"io"
	"net/http"
	"wx-uniapp-go/internal/domain/errcode"
	"wx-uniapp-go/internal/server/echo"
	"wx-uniapp-go/utils"
)

func EncryptionMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		var reqBody struct {
			IsEncrypt bool   `json:"is_encrypt"`
			Data      string `json:"data"`
		}
		body, err := io.ReadAll(c.Request.Body)
		if err != nil {
			echo.Fail(c).Error(errcode.ParametersErr)
			c.AbortWithStatus(http.StatusOK)
			return
		}

		err = json.Unmarshal(body, &reqBody)
		if err != nil {
			echo.Fail(c).Error(errcode.ParametersErr)
			c.AbortWithStatus(http.StatusOK)
			return
		}

		if !reqBody.IsEncrypt {
			// 如果请求的数据未加密，则直接继续处理下一个中间件或处理函数。
			// 将原数据放回缓存, 不然会出现EOF错误
			c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
			c.Next()
			return
		}

		if !reqBody.IsEncrypt {
			// 如果请求的数据未加密，则直接继续处理下一个中间件或处理函数。
			c.Next()
			return
		}

		data, err := utils.AESDecryptECBFromBase64(reqBody.Data, viper.GetString("encrypt.aes-ecb.key"))
		if err != nil {
			echo.Fail(c).Error(errcode.ParametersErr)
			c.AbortWithStatus(http.StatusOK)
			return
		}

		// 将解密后的数据放入请求体中，以便后续处理函数可以像往常一样处理JSON数据。
		c.Request.Body = io.NopCloser(bytes.NewBuffer(data))

		c.Next()
	}
}
